--#include "data\config\equip\EquipSynthesisConfigEx.lua" once

-- 道具合成
function ItemSynthesisEx(sysarg, args)
	local nSynthesisType = args[2] --1 普通合成  2 高级合成
	local nType = args[3] -- 兑换的类型
	local nIndex = args[4] --兑换物品的索引
	local nTargetItemId = args[5] --要兑换的ID
	local isHero = args[6] --是否英雄合成

	--print(nSynthesisType, nType, nIndex, nTargetItemId)
	--判断配置是否存在
	local typeConfig = EquipSynthesisConfigEx[nSynthesisType]
	if not typeConfig then
		return
	end

	local config = typeConfig[nType]
	if not config then
		return
	end

	local nJob = Actor.getIntProperty(sysarg, PROP_ACTOR_VOCATION)
	if isHero == 1 then
		nJob = Hero.getHeroVocation(sysarg)
	end
	local synthesisCfg = config.synthesis[nJob][nIndex]
	if not synthesisCfg then
		return
	end

	if synthesisCfg.level and not Actor.checkActorLevel( sysarg, synthesisCfg.level[2], synthesisCfg.level[1] ) then
		return
	end

	local days = System.getDaysSinceOpenServer()
	local cdays = System.getDaysSinceCombineServer()
	local openday = synthesisCfg.openday or 0
	local combineday = synthesisCfg.combineday or 0
	local isDayCheck = true
	if openday > 0 then
		if days < openday then
			if combineday <= 0 then
				isDayCheck = false
			elseif combineday > 0 and cdays < combineday then
				isDayCheck = false
			end
		end
	else
		if combineday > 0 and cdays < combineday then
			isDayCheck = false
		end
	end

	if not isDayCheck then
		return
	end

	local award = synthesisCfg.award
	if not award or award.id ~= nTargetItemId then
		return 
	end

	local synFunc = DoItemSynthesis[nSynthesisType] or DoEquipSynthesis 
	local ret = synFunc(sysarg, synthesisCfg, args)

	if ret <= 0 then
		SendSynthesisRelust(sysarg, 0, nSynthesisType, 0);
		return
	end

	local successName = Item.getItemName(award.id)
	Actor.sendTipmsg(sysarg, string.format(Lang.ScriptTips.eoh0004, successName), ttFlyTip)
	SendSynthesisRelust(sysarg, award.id, nSynthesisType, 1);

	if synthesisCfg.notice then 
		local name = Actor.getName(sysarg)
		local composeStr = Item.getItemLinkMsg(award.id)
		local result = string.format(Lang.ScriptTips.eoh0006, name, composeStr)
		System.broadcastTipmsg(result, ttScreenCenter + ttChatWindow)
	end

	Actor.triggerQuestEvent(sysarg, 48, 3, 1)
	Actor.triggerAchieveEvent(sysarg, 105, 1)
end


-- 下发合成结果
function SendSynthesisRelust(sysarg, itemId, nType, nRet)
	local netPack = DataPack.allocPacket(sysarg, 8, 19)
	DataPack.writeWord(netPack, itemId)
	DataPack.writeByte(netPack, nType)
	DataPack.writeByte(netPack, nRet)
	DataPack.flush(netPack)
end

-- 通用合成
function DoCommonSynthesis(sysarg, synthesisItemCfg, args)
	if synthesisItemCfg == nil then 
		return -1 
	end
	
	local award = synthesisItemCfg.award
	if not Awards.CheckBagGridCount(sysarg, {award}) then
		return -1
	end

	-- 检测材料是否足够
	local consume = synthesisItemCfg.consume
	if not CheckConsumeCond(sysarg, consume) then
		return -1 
	end

	local nItemCount = args[7]		-- 装备数量
	local packet = args[8]			-- 装备guid列表

	local nNeedItemCount = synthesisItemCfg.equip and #synthesisItemCfg.equip or 0
	if nItemCount ~= nNeedItemCount then
		return -1
	end

	local nEquipItemPtr = {}   --存储物品指针用来最后删除
	local nEquipGuidList = {}  --把取出的每个物品的GUID储存,用来检测是否已存在一样的,有则是通过非法手段来进行
	for i = 1,nItemCount do
		local itemGuid = DataPack.readDouble(packet)
		if not CheckSameGuid(nEquipGuidList, itemGuid) then 
			return -1
		end
	
		local itemPtr = Item.getBagItemPtrByGuid(sysarg, itemGuid)
		if not itemPtr then
			return -1
		end

		local nItemId = Item.getItemId(itemPtr)
		if nItemId ~= synthesisItemCfg.equip[i] then
			return -1
		end

		-- 保存装备指针
		table.insert(nEquipGuidList, itemGuid)
		table.insert(nEquipItemPtr, itemPtr)
	end

	-- 扣除材料
	DoConsumeCond(sysarg, consume, 1, GameLog.cNewEquipSynthesisConsume, Lang.ScriptTips.EquipSyn002)

	local nNewStar = 0
	local nNewInject = 0
	local nNewLuck = 0
	for i=1, #nEquipItemPtr do	
		local tempStar	= Item.getItemProperty( sysarg, nEquipItemPtr[i], Item.ipItemStrong, 0)				--强化星级
		local tempInject= Item.getItemProperty( sysarg, nEquipItemPtr[i], Item.ipItemInjectLevel, 0)		--注灵等级
		local tempLuck 	= Item.getItemProperty( sysarg, nEquipItemPtr[i], Item.ipItemLuck, 0)				--幸运（诅咒）
		if tempStar > nNewStar then
			nNewStar = tempStar
		end
		if tempInject > nNewInject then
			nNewInject = tempInject
		end
		if tempLuck > nNewLuck then
			nNewLuck = tempLuck
		end

		Actor.removeItemByPtr(sysarg, nEquipItemPtr[i], 1, true, Lang.ScriptTips.EquipSyn002, GameLog.cNewEquipSynthesisConsume)
	end
	if nNewStar > 0 then
		nNewStar = nNewStar - 1
	end
	if nNewInject > 0 then
		nNewInject = nNewInject - 1
	end

	if synthesisItemCfg.rate < 10000 then
		if math.random(1, 10000) > synthesisItemCfg.rate then
			Actor.sendTipmsg(sysarg, string.format(Lang.ScriptTips.eoh0003, Item.getItemName(award.id)), ttFlyTip)
			return 0
		end
	end

	local nNewItem = Item.createItem(award.id, award.count, nNewStar, 0, award.bind or 1)
	Item.addItem(sysarg, nNewItem, Lang.ScriptTips.EquipSyn003, GameLog.clEquipSynthesize)
	if nNewInject > 0 then
		Item.setItemProperty( sysarg, nNewItem, Item.ipItemInjectLevel, nNewInject) 
	end
	local equipType = Item.getItemPropertyById(award.id, Item.ipItemType)
	if equipType == Item.itWeapon and nNewLuck > 0 then	
		Item.setItemProperty( sysarg, nNewItem, Item.ipItemLuck, nNewLuck)
	end

	return 1
end

-- 材料合成
function DoMaterialSynthesis(sysarg, synthesisItemCfg, args)
	if synthesisItemCfg == nil then 
		return -1 
	end
	
	-- 检测材料是否足够
	local consume = synthesisItemCfg.consume
	if not CheckConsumeCond(sysarg, consume) then
		return -1 
	end
	 
	local award = synthesisItemCfg.award
	if not Awards.CheckBagGridCount(sysarg, {award}) then
		return -1
	end

	-- 扣除材料
	DoConsumeCond(sysarg, consume, 1, GameLog.cNewEquipSynthesisConsume, Lang.ScriptTips.EquipSyn002)
	if synthesisItemCfg.rate < 10000 then
		if math.random(1, 10000) > synthesisItemCfg.rate then
			Actor.sendTipmsg(sysarg, string.format(Lang.ScriptTips.eoh0003, Item.getItemName(award.id)), ttFlyTip)
			return 0 -- 不命中
		end
	end

	-- 创建新的道具
	local nNewItem = Item.createItem(award.id, award.count, award.strong or 0, 0, award.bind or 1)
	Item.addItem(sysarg, nNewItem, Lang.ScriptTips.EquipSyn003, GameLog.clEquipSynthesize)
	
	return 1 -- 命中
end


-- 返回负数失败; 0 有合成但不命中; 1 有合成且命中
function DoEquipSynthesis(sysarg, synthesisItemCfg, args)
	if synthesisItemCfg == nil then 
		return -1 
	end
	
	local award = synthesisItemCfg.award
	if not Awards.CheckBagGridCount(sysarg, {award}) then
		return -1
	end

	local tNonEquip = {}
	local materialItemPtrs = {}
	
	local consume = synthesisItemCfg.consume
	for _, tab in ipairs(consume) do
		if tab.type ~= 0 and tab.type ~= 128 then
			table.insert(tNonEquip, tab)
		elseif tab.type == 0 then
			local itemPtrList = LuaHelp.getItemListByItemId(sysarg, tab.id, 0)
			if itemPtrList == nil or #itemPtrList < tab.count then
				Actor.sendTipmsg(sysarg, Lang.ScriptTips.EquipSyn001, ttFlyTip)
				return -1
			end
			
			for i = 1, tab.count do
				local itemptr = itemPtrList[i]
				table.insert(materialItemPtrs, itemptr)
			end			
		else
			local totalCount = tab.count
			for _, v in ipairs(tab.id) do
				local itemNum = 0
				local itemPtrList = LuaHelp.getItemListByItemId(sysarg,	v, 0)
				if itemPtrList then
					 itemNum = #itemPtrList
				end
				if itemNum >= totalCount then
					for i = 1, totalCount do
						local itemptr = itemPtrList[i]
						table.insert(materialItemPtrs, itemptr)
					end		
					totalCount = 0
					break
				else
					for i = 1, itemNum do
						local itemptr = itemPtrList[i]
						table.insert(materialItemPtrs, itemptr)
					end		
					totalCount = totalCount - itemNum
				end
			end
			
			if totalCount > 0 then
				Actor.sendTipmsg(sysarg, Lang.ScriptTips.EquipSyn001, ttFlyTip)
				return -1
			end
		end
	end

	-- 检测材料是否足够
	if not CheckConsumeCond( sysarg, tNonEquip ) then
		return  -1
	end
	
	local nNewStar = 0
	local nNewInject = 0
	local nNewLuck = 0
	local isWeapon = false
	local equipType = Item.getItemPropertyById(award.id, Item.ipItemType)
	if equipType == Item.itWeapon then	
		isWeapon = true
	end

	--扣除材料及费用
	DoConsumeCond(sysarg, tNonEquip, 1, GameLog.cNewEquipSynthesisConsume, Lang.ScriptTips.EquipSyn002)
	for i=1, #materialItemPtrs do	
		local tempStar	= Item.getItemProperty( sysarg, materialItemPtrs[i], Item.ipItemStrong, 0)				--强化星级
		local tempInject= Item.getItemProperty( sysarg, materialItemPtrs[i], Item.ipItemInjectLevel, 0)		--注灵等级
		if tempStar > nNewStar then
			nNewStar = tempStar
		end
		if tempInject > nNewInject then
			nNewInject = tempInject
		end
		if isWeapon then
			local tempLuck = Item.getItemProperty(sysarg, materialItemPtrs[i], Item.ipItemLuck, 0)				--幸运（诅咒）
			if tempLuck > nNewLuck then
				nNewLuck = tempLuck
			end
		end
		Actor.removeItemByPtr(sysarg, materialItemPtrs[i], 1, true, Lang.ScriptTips.EquipSyn002, GameLog.cNewEquipSynthesisConsume)
	end
	if nNewStar > 0 then
		nNewStar = nNewStar - 1
	end
	if nNewInject > 0 then
		nNewInject = nNewInject - 1
	end

	if synthesisItemCfg.rate < 10000 then
		if math.random(1, 10000) > synthesisItemCfg.rate then
			Actor.sendTipmsg(sysarg, string.format(Lang.ScriptTips.eoh0003, Item.getItemName(award.id)), ttFlyTip)
			return 0 -- 不命中
		end
	end

	-- 创建新的装备
	local nNewItem = Item.createItem(award.id, award.count, nNewStar, 0, award.bind or 1)
	Item.addItem(sysarg, nNewItem, Lang.ScriptTips.EquipSyn003, GameLog.clEquipSynthesize)
	if nNewInject > 0 then
		Item.setItemProperty( sysarg, nNewItem, Item.ipItemInjectLevel, nNewInject) 
	end
	if isWeapon and nNewLuck > 0 then
		Item.setItemProperty(sysarg, nNewItem, Item.ipItemLuck, nNewLuck)
	end

	return 1 -- 命中
end

-- 返回负数失败; 0 有合成但不命中; 1 有合成且命中
function DoEquipExchangeEx(sysarg, synthesisItemCfg, args)
	if synthesisItemCfg == nil then 
		return -1 
	end
	
	local award = synthesisItemCfg.award
	if not Awards.CheckBagGridCount(sysarg, {award}) then
		return -1
	end

	-- 检测材料是否足够
	local consume = synthesisItemCfg.consume
	if not CheckConsumeCond(sysarg, consume) then
		return -1 
	end

	local nItemCount = args[7]		-- 装备数量
	local packet = args[8]			-- 装备guid列表

	if nItemCount ~= 1 then
		return -1
	end
	local nNeedItemCount = synthesisItemCfg.equip and #synthesisItemCfg.equip or 0
	if nItemCount ~= nNeedItemCount then
		return -1
	end

	local itemGuid = DataPack.readDouble(packet)
	local equipPtr = Item.getBagItemPtrByGuid(sysarg, itemGuid)
	if not equipPtr then
		return -1
	end

	local nItemId = Item.getItemId(equipPtr)
	if nItemId ~= synthesisItemCfg.equip[1] then
		return -1
	end

	DoConsumeCond(sysarg, consume, 1, GameLog.cNewEquipSynthesisConsume, Lang.ScriptTips.EquipSyn002)

	local equipStar  	= Item.getItemProperty( sysarg, equipPtr, Item.ipItemStrong, 0)				--强化星级
	local lostStar		= Item.getItemProperty( sysarg, equipPtr, Item.ipItemLostStar, 0)			--损失星级
	local equipInject  	= Item.getItemProperty( sysarg, equipPtr, Item.ipItemInjectLevel, 0)		--注灵等级
	local equipLuck 	= Item.getItemProperty( sysarg, equipPtr, Item.ipItemLuck, 0)				--幸运（诅咒）

	local newEquipPtr = Item.createItem(award.id, award.count, equipStar, 0, award.bind or 1)
	Item.transSmithAttrs( equipPtr, newEquipPtr )			--进行洗练属性转移，此时原装备必须存在
	Actor.removeItemByPtr(sysarg, equipPtr, 1, true, Lang.ScriptTips.EquipSyn002, GameLog.cNewEquipSynthesisConsume)
	Item.addItem(sysarg, newEquipPtr, Lang.ScriptTips.EquipSyn003, GameLog.clEquipSynthesize)
	
	Item.setItemProperty( sysarg, newEquipPtr, Item.ipItemLostStar, lostStar) 
	Item.setItemProperty( sysarg, newEquipPtr, Item.ipItemInjectLevel, equipInject) 
	Item.setItemProperty( sysarg, newEquipPtr, Item.ipItemLuck, equipLuck)
	
	return 1 -- 命中
end

-- 返回负数失败; 0 有合成但不命中; 1 有合成且命中
function DoEquipExchange(sysarg, synthesisItemCfg, args)
	if synthesisItemCfg == nil then 
		return -1 
	end
	
	local award = synthesisItemCfg.award
	if not Awards.CheckBagGridCount(sysarg, {award}) then
		return -1
	end

	local tNonEquip = {}
	local equipPtr = nil
	
	local consume = synthesisItemCfg.consume
	for _, tab in ipairs(consume) do
		if tab.type ~= 0 then
			table.insert(tNonEquip, tab)
		elseif tab.type == 0 and equipPtr == nil then
			local itemPtrList = LuaHelp.getItemListByItemId(sysarg, tab.id, 0)
			if itemPtrList == nil then
				Actor.sendTipmsg(sysarg, Lang.ScriptTips.EquipSyn001, ttFlyTip)
				return -1
			end
			equipPtr = itemPtrList[1]
		end
	end

	-- 检测材料是否足够
	if not CheckConsumeCond( sysarg, tNonEquip ) then
		return  -1
	end

	if not equipPtr then
		return -1
	end
	
	DoConsumeCond(sysarg, tNonEquip, 1, GameLog.cNewEquipSynthesisConsume, Lang.ScriptTips.EquipSyn002)

	local equipStar  	= Item.getItemProperty( sysarg, equipPtr, Item.ipItemStrong, 0)				--强化星级
	local lostStar		= Item.getItemProperty( sysarg, equipPtr, Item.ipItemLostStar, 0)			--损失星级
	local equipInject  	= Item.getItemProperty( sysarg, equipPtr, Item.ipItemInjectLevel, 0)		--注灵等级
	local equipLuck 	= Item.getItemProperty( sysarg, equipPtr, Item.ipItemLuck, 0)				--幸运（诅咒）

	local newEquipPtr = Item.createItem(award.id, award.count, equipStar, 0, award.bind or 1)
	Item.transSmithAttrs( equipPtr, newEquipPtr )			--进行洗练属性转移，此时原装备必须存在
	Actor.removeItemByPtr(sysarg, equipPtr, 1, true, Lang.ScriptTips.EquipSyn002, GameLog.cNewEquipSynthesisConsume)
	Item.addItem(sysarg, newEquipPtr, Lang.ScriptTips.EquipSyn003, GameLog.clEquipSynthesize)
	
	Item.setItemProperty( sysarg, newEquipPtr, Item.ipItemLostStar, lostStar) 
	Item.setItemProperty( sysarg, newEquipPtr, Item.ipItemInjectLevel, equipInject) 
	Item.setItemProperty( sysarg, newEquipPtr, Item.ipItemLuck, equipLuck)
	
	return 1 -- 命中
end

DoItemSynthesis = {
	DoEquipSynthesis,
	DoMaterialSynthesis,
	DoMaterialSynthesis,
	DoEquipExchange,
	DoMaterialSynthesis,
	DoMaterialSynthesis,
}

